package me.softwareengineer.guice.rendering.domain;

import java.util.List;

/**
 * Defines wrapper {@link Element}. Wrapper element has one or more children of
 * {@link Element}
 * 
 * @author yadtahir
 * 
 */
public interface HasChildren {

	/**
	 * Adds the given element to the end of the children list of the current
	 * element.
	 * 
	 * @param elementToAdd
	 *            the child block to add
	 *            <p>
	 *            This method is a thread-safe method and can be accessed
	 *            concurrently
	 *            </p>
	 */
	void addChild(Element elementToAdd);

	/**
	 * Adds several children elements to the end of the children list of the
	 * current block.
	 * 
	 * @param elementsToAdd
	 *            the children blocks to add
	 *            <p>
	 *            This method is a thread-safe method and can be accessed
	 *            concurrently
	 *            </p>
	 */
	void addChildren(List<Element> elementsToAdd);

	/**
	 * Gets all children elements
	 * 
	 * @return an unmodifiable list of the sub elements
	 */
	List<Element> getChildren();

	/**
	 * Adds the provided {@link Element} after the existing child element
	 * 
	 * @param existingElement
	 * @param elementToInsert
	 *            element to add
	 *            <p>
	 *            This method is a thread-safe method and can be accessed
	 *            concurrently
	 *            </p>
	 */
	void insertChildAfter(Element elementToInsert, Element existingElement);

	/**
	 * Adds the provided {@link Element} before the existing child block
	 * 
	 * @param existingElement
	 * @param elementToInsert
	 *            element to add
	 *            <p>
	 *            This method is a thread-safe method and can be accessed
	 *            concurrently
	 *            </p>
	 */
	void insertChildBefore(Element elementToInsert, Element existingElement);

	/**
	 * Removes provided #{@link Element} from the list.
	 * 
	 * @param childElementToRemove
	 *            the child element to remove
	 *            <p>
	 *            This method is a thread-safe method and can be accessed
	 *            concurrently
	 *            </p>
	 */
	void removeElement(Element childElementToRemove);

	/**
	 * Replaces the existing child element with the provided element
	 * 
	 * @param existingChild
	 *            the old child, which is going to be replaced
	 * @param newChild
	 *            the new child
	 *            <p>
	 *            This method is a thread-safe method and can be accessed
	 *            concurrently
	 *            </p>
	 */
	void replaceChild(Element existingChild, Element newChild);

	/**
	 * Helper method replaces the existing child with the new elements. In
	 * addition, it sets the parent of new elements to the current element
	 * 
	 * @param exstingChild
	 *            old child, which is going to be replaced
	 * @param newElements
	 *            new elements
	 *            <p>
	 *            This method is a thread-safe method and can be accessed
	 *            concurrently
	 *            </p>
	 */
	void replaceChild(Element exstingChild, List<? extends Element> newElements);

	/**
	 * Replaces the current children list by the given list of {@link #Element}.
	 * 
	 * @param elementsToReplace
	 *            <p>
	 *            This method is a thread-safe method and can be accessed
	 *            concurrently
	 *            </p>
	 */
	void setChildren(List<Element> elementsToReplace);

}
